﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using XSockets.Core.Globals;
using XSockets.Core.XSocket;
using XSockets.Core.XSocket.Event.Arguments;
using XSockets.Core.XSocket.Event.Attributes;
using XSockets.Core.XSocket.Helpers;
using XSockets.Core.XSocket.Interface;
using XSockets.WebRTC.Prototype.Shared.Handlers.Model;

namespace XSockets.WebRTC.Prototype.Shared.Handlers
{
    [Export(typeof(IXBaseSocket))]
    [XBaseSocketMetadata("SignalingController", Constants.GenericTextBufferSize)]
    public class SignalingController : XBaseSocket
    {
        /// <summary>
        /// List of connected Peer's (Clients)
        /// </summary>
        protected static List<Peer> Peers { get; set; }
        public SignalingController()
        {
            this.OnClientConnect += new EventHandler<OnClientConnectArgs>(SignalHandler_OnClientConnect);
            this.OnClientDisConnect += new EventHandler<OnClientDisConnectArgs>(SignalHandler_OnClientDisConnect);
        }

        void SignalHandler_OnClientConnect(object sender, OnClientConnectArgs e)
        {
            var peer = new Peer { Identity = e.XNode.Guid };
            Peers.Add(peer);
            this.AsyncSend(peer, "onpeercreated");
            this.AsyncSendToAll(new { Peers = SignalingController.Peers.Count }, "onnumofpeerschanged");
        }

        void SignalHandler_OnClientDisConnect(object sender, OnClientDisConnectArgs e)
        {
            var peer = SignalingController.Peers.Single(p => p.Identity.Equals(e.XNode.Guid));
            Peers.Remove(peer);
            this.AsyncSendToAll(Peers, "onpeerdisconnected");
            this.AsyncSendToAll(new { Peers = SignalingController.Peers.Count }, "onnumofpeerschanged");
        }
        [HandlerEvent("Offer")]
        public void OnOfferPeer(SignalMessage signalMessage)
        {
            this.AsyncSendTo(to => to.Guid.Equals(signalMessage.For), signalMessage, "onoffer");
        }

        [HandlerEvent("SetNick")]
        public void SetNickName(Peer peer)
        {
            var current = Peers.Single(p => p.Identity.Equals(peer.Identity));
            current.NickName = peer.NickName;
            var node = SignalingController.Peers.Where(c => !string.IsNullOrEmpty(c.NickName));
            this.AsyncSendToAll(node, "onpeerconnected");
        }
        [HandlerEvent("Answer")]
        public void OnSendAnswer(SignalMessage signalMessage)
        {
            this.AsyncSendTo(to => to.Guid.Equals(signalMessage.For), signalMessage, "onanswer");
        }

        [HandlerEvent("Stop")]
        public void OnStop(Peer peer)
        {
            this.AsyncSendTo(to => to.Guid.Equals(peer.Identity), peer, "onstop");
        }
        
        [HandlerEvent("Start")]
        public void OnStartCall(Peer peer)
        {
                // todo: We want need this futher on.. just lazy..
            this.AsyncSendTo(to => to.Guid.Equals(peer.Identity), peer, "onstart");
        }

        [HandlerEvent("Complete")]
        public void OnComplated(SignalMessage signalMessage)
        {
            this.AsyncSendTo(to => to.Guid.Equals(signalMessage.For), signalMessage, "oncompleted");
            Peers.Single(p => p.Identity.Equals(signalMessage.By)).Busy = true;
            this.AsyncSendToAll(Peers, "ontalks");
            
        }
        static SignalingController()
        {
            SignalingController.Peers = new List<Peer>();
        }
        public override IXBaseSocket NewInstance()
        {
            return new SignalingController();
        }
    }
}